﻿using SimpleTool.Base;
using System.Windows;
using Serilog;
using System.Collections.ObjectModel;
using System.Windows.Documents;
using Microsoft.Xaml.Behaviors;
using System.Windows.Input;
using SimpleTool.SerialTool.SerialControl;
using SimpleTool.Server;
using System.IO.Ports;
using SimpleTool.SerialTool;
using SimpleTool.Capacity;
using SimpleTool.ActivityUnit;
using System.Windows.Media;
using SimpleTool.TransformComponent;
using System.Threading.Tasks;
using SimpleTool.ActivityUnit.EchoControl;
using System.Windows.Threading;
using CommunityToolkit.Mvvm.Messaging;

namespace SimpleTool
{
    enum FuncType
    {
        Invalid,
        Global,
        Serial,
        Capacity,
        Activity
    }

    class MainViewModel : Notify
    {
        public FuncType CurrentPageType = FuncType.Invalid;

        private MainSectionModel? MainTemplateModel;

        private IDatabaseServer DatabaseServer;

        private readonly ILogger Logger = Log.ForContext<MainViewModel>();

        
        public MainViewModel(IDatabaseServer databaseServer)
        {
            DatabaseServer = databaseServer;
            _= DBinit(DBreserveInfo.IsCloudConnect);
            FunctionSelectChange(1);
        }

        public async Task DBinit(bool isCloud = true, bool isAbnormal = false)
        {
            if (DatabaseServer is not null)
            {
                if (isCloud)
                {
                    bool isInit = await DatabaseServer.InitCloudDB(DatabaseServer.GetImportantInfo().Key, DatabaseServer.GetImportantInfo().Value);
                    if (!isInit)
                    {
                        CustomMessageBox.Show("云数据库连接异常", 1, ["知道了"], "因为云数据库连接失败，暂时无法使用，正在尝试切换至本地数据库");
                        await DBinit(false, true);
                        Logger.WarningElite("cloud init fail");
                    }
                    else
                    {
                        DBreserveInfo.SelectionAddress = "云数据库";
                        DBreserveInfo.Selectionkey = "云数据库";
                        DatabaseServer.TemporaryRelease(true); //释放原数据库资源
                        Logger.WarningElite("cloud init finish");
                    }
                }
                else
                {
                    DatabaseServer?.InitLocalDB(new SqliteConnectionConfig
                    {
                        Path = DatabaseServer.GetImportantInfo(false).Key,
                        Name = DBreserveInfo.LocalDBName,
                        EncryptValue = DBreserveInfo.LocalDBcryptKey[0],
                        EncryptKey = DBreserveInfo.LocalDBcryptKey[1]
                    });

                    if (DatabaseServer is not null)
                    {
                        DBreserveInfo.SelectionAddress = "本地数据库";
                        DBreserveInfo.Selectionkey = "Auto";
                        DatabaseServer.TemporaryRelease(false);//释放原数据库资源
                    }
                }

                if (isAbnormal) ReffleUpdate(); ;
            }
        }

        public async Task DatabaseQuestion()
        {
            CustomMessageBox.ConfigOption configOption = CustomMessageBox.Show("公共配置", ["取消", "确定"], new CustomMessageBox.ConfigOption()
            {
                CurrentApplyDBaddress = DBreserveInfo.SelectionAddress,
                CurrentApplyDBkey = DBreserveInfo.Selectionkey,
            });

            if (configOption.index == 1)
            {
                if (configOption.CurrentApplyDBaddress == "云数据库")
                {
                    if (configOption.CurrentApplyDBkey != "云数据库")
                    {
                        DatabaseServer.SetImportantInfo(new KeyValuePair<string, string>(
                            DatabaseServer.GetImportantInfo().Key,
                            configOption.CurrentApplyDBkey), true);
                        DBreserveInfo.SelectionAddress = DatabaseServer.GetImportantInfo().Key;
                        DBreserveInfo.Selectionkey = configOption.CurrentApplyDBkey;
                    }
                    else
                    {
                        DBreserveInfo.SelectionAddress = "云数据库";
                        DBreserveInfo.Selectionkey = "云数据库";
                    }

                    await DBinit();

                    ReffleUpdate();

                }
                else if (configOption.CurrentApplyDBaddress == "本地数据库")
                {
                    if (configOption.CurrentApplyDBkey == "云数据库")
                    {
                        DatabaseServer.SetImportantInfo(new KeyValuePair<string, string>(
                            DatabaseServer.GetImportantInfo(false).Key,
                            DatabaseServer.GetImportantInfo().Value), false);
                        DBreserveInfo.SelectionAddress = DatabaseServer.GetImportantInfo(false).Key;
                        DBreserveInfo.Selectionkey = DatabaseServer.GetImportantInfo().Value;

                    }
                    else if (configOption.CurrentApplyDBkey != "Auto")
                    {
                        DatabaseServer.SetImportantInfo(new KeyValuePair<string, string>(
                            DatabaseServer.GetImportantInfo(false).Key,
                            configOption.CurrentApplyDBkey), false);
                        DBreserveInfo.SelectionAddress = DatabaseServer.GetImportantInfo(false).Key;
                        DBreserveInfo.Selectionkey = configOption.CurrentApplyDBkey;
                    }
                    await DBinit(false);

                    ReffleUpdate();
                }
                else
                {
                    if (!string.IsNullOrEmpty(configOption.CurrentApplyDBaddress) && !string.IsNullOrEmpty(configOption.CurrentApplyDBkey))
                    {
                        DBreserveInfo.SelectionAddress = configOption.CurrentApplyDBaddress;
                        DBreserveInfo.Selectionkey = configOption.CurrentApplyDBkey;

                        await DBinit(true);

                        ReffleUpdate();
                    }
                }
            }
        }

        // 数据库切换重连
        private void ReffleUpdate()
        {
            if (ControlContent is OverViewControl viewControl && viewControl.HoldOverViewModel is not null)
            {
                WeakReferenceMessenger.Default.Send<MvvmMessage>(new MvvmMessage(MvvmMessage.MvvmType.Database_ActivityStart));
            }
            else if (ControlContent is Activity activity && activity.HoldActivitViewModel is not null)
            {
                activity.HoldActivitViewModel.DBconnectStart();
            }
        }

        public ICommand FuncSelectCommand
        {
            set
            {
                MainSectionModel.FuncSelectedStdin = value;
                propertyChangeSend(nameof(FuncSelectCommand));
            }
            get
            {
                MainSectionModel.FuncSelectedStdin ??= new EasyCommand(FunctionSelectChange, bool () => { return true; });
                return MainSectionModel.FuncSelectedStdin;
            }
        }

        public ObservableCollection<MainFuncListItem> MainFuncListItems { set; get; } = [];

        public VerticalAlignment FuncListVerticalAlign
        {
            set
            {
                MainSectionModel.FuncListVerticalAlign = value;
            }
            get
            {
                return MainSectionModel.FuncListVerticalAlign;
            }
        }

        public MainSectionModel MainSectionModel
        {
            set
            {
                MainTemplateModel = value;
                propertyChangeSend(nameof(MainSectionModel));
            }
            get
            {
                MainTemplateModel ??= new MainSectionModel();
                return MainTemplateModel;
            }
        }

        public object ControlContent
        {
            set
            {
                MainSectionModel.ControlContentStdin = value;
                propertyChangeSend(nameof(ControlContent));
            }
            get
            {
                MainSectionModel.ControlContentStdin ??= new object();
                return MainSectionModel.ControlContentStdin;
            }
        }

        private async void FunctionSelectChange(object? selected)
        {
            int OptionType = (int)(selected ?? 0);
            switch (OptionType)
            {
                case 0:
                    switch (CurrentPageType)
                    {
                        case FuncType.Invalid:
                        case FuncType.Global:
                            await DatabaseQuestion();
                            break;
                        case FuncType.Serial:
                        case FuncType.Activity:
                        case FuncType.Capacity:
                            FuncListChange(FuncType.Global);
                            break;
                    }
                    break;
                case 1:
                    switch (CurrentPageType)
                    {
                        case FuncType.Invalid:
                        case FuncType.Global:

                            _ = Task.Run(() =>
                            {
                                Application.Current.Dispatcher.InvokeAsync(() =>
                                {
                                    OverViewControl UI = new()
                                    {
                                        ConfigPageType = 2
                                    };
                                    ControlContent = UI;
                                }, DispatcherPriority.Background);
                            });

                            FuncListChange(FuncType.Serial);
                            break;
                        case FuncType.Serial:
                            await DatabaseQuestion();
                            break;
                        case FuncType.Activity:
                            await DatabaseQuestion();
                            break;
                    }
                    break;
                case 2:
                    switch (CurrentPageType)
                    {
                        case FuncType.Global:

                            _ = Task.Run(() =>
                            {
                                Application.Current.Dispatcher.InvokeAsync(() =>
                                {
                                    CapacityControl UI = new();
                                    ControlContent = UI;
                                }, DispatcherPriority.Background);
                            });

                            FuncListChange(FuncType.Capacity);
                            break;
                        case FuncType.Serial:
                            ((OverViewControl)ControlContent).ConfigPageType = 2;
                            break;
                    }
                    break;

                case 3:
                    switch (CurrentPageType)
                    {
                        case FuncType.Global:

                            _ = Task.Run(() =>
                            {
                                Application.Current.Dispatcher.InvokeAsync(() =>
                                {
                                    Activity UI = new();
                                    ControlContent = UI;
                                }, DispatcherPriority.Background);
                            });

                            FuncListChange(FuncType.Activity);
                            break;
                        case FuncType.Serial:
                            ((OverViewControl)ControlContent).ConfigPageType = 3;
                            break;
                    }
                    break;

                case 4:
                    switch (CurrentPageType)
                    {
                        case FuncType.Global:
                            break;
                        case FuncType.Serial:
                            ((OverViewControl)ControlContent).ConfigPageType = 4;
                            break;
                    }
                    break;
            }
        }

        public void FuncListChange(FuncType Type)
        {
            if (Type != CurrentPageType)
            {
                MainFuncListItems.Clear();
                CurrentPageType = Type;
                switch (Type)
                {
                    case FuncType.Global:
                        MainFuncListItems.Add(new MainFuncListItem
                        {
                            Content = "\ue625", // public config
                            Family = "Icon".FindSource<FontFamily>() ?? new FontFamily("YaHei"),
                            FontWeight = FontWeights.UltraLight,
                            TipHint = "配置"
                        });
                        MainFuncListItems.Add(new MainFuncListItem
                        {
                            Content = "\ue633", // serial
                            Family = "Icon".FindSource<FontFamily>() ?? new FontFamily("YaHei"),
                            FontWeight = FontWeights.Light,
                            TipHint = "串口工具"
                        });

                        MainFuncListItems.Add(new MainFuncListItem
                        {
                            Content = "\ue687", //capacity test
                            Family = "Icon".FindSource<FontFamily>() ?? new FontFamily("YaHei"),
                            FontWeight = FontWeights.Light,
                            TipHint = "测量工具"
                        });

                        MainFuncListItems.Add(new MainFuncListItem
                        {
                            Content = "\ue64c", //pro test
                            Family = "Icon".FindSource<FontFamily>() ?? new FontFamily("YaHei"),
                            FontWeight = FontWeights.Light,
                            TipHint = "产测工具"
                        });
                        break;
                    case FuncType.Serial:
                        MainFuncListItems.Add(new MainFuncListItem
                        {
                            Content = "\ue609", // global
                            Family = "Icon".FindSource<FontFamily>() ?? new FontFamily("YaHei"),
                            FontWeight = FontWeights.Light,
                            TipHint = "菜单"
                        });
                        MainFuncListItems.Add(new MainFuncListItem
                        {
                            Content = "\ue625", // public config
                            Family = "Icon".FindSource<FontFamily>() ?? new FontFamily("YaHei"),
                            FontWeight = FontWeights.UltraLight,
                            TipHint = "配置"
                        });
                        MainFuncListItems.Add(new MainFuncListItem
                        {
                            Content = "\ue661", // serial basic config
                            Family = "Icon".FindSource<FontFamily>() ?? new FontFamily("YaHei"),
                            FontWeight = FontWeights.Light,
                            TipHint = "串口配置",
                            Fontsize = 25
                        });
                        MainFuncListItems.Add(new MainFuncListItem
                        {
                            Content = "\ue614", // command
                            Family = "Icon".FindSource<FontFamily>() ?? new FontFamily("YaHei"),
                            FontWeight = FontWeights.Light,
                            TipHint = "串口指令"
                        });
                        MainFuncListItems.Add(new MainFuncListItem
                        {
                            Content = "\ue7d9", //higt light
                            Family = "Icon".FindSource<FontFamily>() ?? new FontFamily("YaHei"),
                            FontWeight = FontWeights.Light,
                            TipHint = "串口高亮"
                        });
                        break;

                    case FuncType.Activity:
                        MainFuncListItems.Add(new MainFuncListItem
                        {
                            Content = "\ue609", // global
                            Family = "Icon".FindSource<FontFamily>() ?? new FontFamily("YaHei"),
                            FontWeight = FontWeights.Light,
                            TipHint = "菜单"
                        });
                        MainFuncListItems.Add(new MainFuncListItem
                        {
                            Content = "\ue625", // public config
                            Family = "Icon".FindSource<FontFamily>() ?? new FontFamily("YaHei"),
                            FontWeight = FontWeights.UltraLight,
                            TipHint = "配置"
                        });
                        break;
                    case FuncType.Capacity:
                        MainFuncListItems.Add(new MainFuncListItem
                        {
                            Content = "\ue609", // global
                            Family = "Icon".FindSource<FontFamily>() ?? new FontFamily("YaHei"),
                            FontWeight = FontWeights.Light,
                            TipHint = "菜单"
                        });
                        break;
                }
                MainSectionModel.FuncListVerticalAlign = VerticalAlignment.Center;
            }
        }
    
    }
}
